﻿

#include "aiBoss.h"
#include <cmath>
using namespace std;


#define SQR(a) ((a) * (a))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))

/************************************************************************
 * 初始化函数：
 *     参数：
 *         name: Boss的名字
 *     说明：
 *         指定Boss的名字，做一些初始化工作。
 ***********************************************************************/

int cntBulletsNum[5], limitBulletsNum[5];

void init(string& name) {
	name = "Alyssa's Boss";
	srand(time(0));

}

int getBulletType(double vx, double vy) {
    for (int i = 0; i < 5; i ++)
        if (fabs(SQR(vx) + SQR(vy) - SQR(BULLET_V[i])) < EPSILON)
            return i;
    return -1;
}

/************************************************************************
 * 指定Boss动作的函数：
 *     参数：
 *         gameInfo:    当前游戏局面信息
 *         newBullets:  Boss要新发的子弹
 *         msg:         Boss要说的话，可以包括一些调试信息，会输出到录像中
 *     说明：
 *         根据当前游戏局面信息，指定Boss要新发出的子弹。
 ***********************************************************************/

/************************************************************************
 * CurveLine策略：
 *     所有子弹都发出去
 *         同速度的子弹排成一条线扫过去
 ***********************************************************************/
namespace CurveLineTactics
{

const int CurveLineTaticsMargin = 28;
//pair<double,double>aim;
NewBullet newBullet;
inline void BulletStandardization(int i)
{
	newBullet.vx -= BULLET_X;
	newBullet.vy -= BULLET_Y;
	double v = sqrt(newBullet.vx*newBullet.vx + newBullet.vy*newBullet.vy);
	newBullet.vx = BULLET_V[i] * newBullet.vx / v;
	newBullet.vy = BULLET_V[i] * newBullet.vy / v;

}
void Main(const GameInfo& gameInfo, vector<NewBullet>& newBullets,string& msg)
{
	double px = gameInfo.planeX, py = gameInfo.planeY;
	int round = gameInfo.round;
	int availableBulletNum , leftBulletNum;
	double tmp;
	pair<double,double> v;
	int leftNum,rightNum;
	newBullet.initTime = round;
    for (int i = 0; i < 5; i ++) {
    	leftBulletNum = limitBulletsNum[i] - cntBulletsNum[i];
		if (leftBulletNum >= 7)availableBulletNum = 7;
		else availableBulletNum = 0;


		if (availableBulletNum>=1){
			newBullet.vx = px;
			newBullet.vy = py;
			BulletStandardization(i);
			newBullets.push_back(newBullet);
			availableBulletNum--;
		}

		//飞机和boss连线的法向量
		v.first = py-BULLET_Y;
		v.second = BULLET_X-px;

		tmp = sqrt (SQR(v.first)+SQR(v.second));
		v.first  /= tmp;
		v.second /= tmp;

		leftNum = availableBulletNum / 2;
		rightNum = availableBulletNum - leftNum;

		for (int j = 1; j<=leftNum; ++j){
			newBullet.vx = px - v.first*j*CurveLineTaticsMargin;
			newBullet.vy = py - v.second*j*CurveLineTaticsMargin;
			BulletStandardization(i);
			newBullets.push_back(newBullet);
		}
		for (int j = 1; j<=rightNum; ++j){
			newBullet.vx = px + v.first*j*CurveLineTaticsMargin;
			newBullet.vy = py + v.second*j*CurveLineTaticsMargin;
			BulletStandardization(i);
			newBullets.push_back(newBullet);
		}

    }



}

}
void getAction(const GameInfo& gameInfo, vector<NewBullet>& newBullets, string& msg) {


    memset(cntBulletsNum, 0, sizeof(cntBulletsNum));
    for (int i = 0; i < 5; i ++)
        limitBulletsNum[i] = (int)(BULLET_INIT_LIMIT[i] * BULLET_INCREASE(gameInfo.round));

    for (int i = 0; i < gameInfo.bullets.size(); i ++) {
    	int type = getBulletType(gameInfo.bullets[i].vx, gameInfo.bullets[i].vy);
    	cntBulletsNum[type] ++;
    }
	CurveLineTactics::Main(gameInfo,newBullets,msg);


	msg = "Haha";
}

